﻿using System;
using System.Numerics;
using System.Text;
using NUnit.Framework;

namespace BinIntegerMultiplication
{
    [TestFixture]
    public class Tests
    {
        [Test]
        [TestCase("0", "0", "0")]
        [TestCase("5", "0", "5")]
        [TestCase("23", "8", "31")]
        [TestCase("156", "894", "1050")]
        [TestCase("123456789", "6984657315456875564", "6984657315580332353")]
        public void SumTests(string int1, string int2, string expectedSum)
        {
            MyBigInteger first = new MyBigInteger(int1);
            MyBigInteger second = new MyBigInteger(int2);
            MyBigInteger expected = new MyBigInteger(expectedSum);

            Assert.AreEqual(expected, first + second);
        }

        [Test]
        [TestCase(100)]
        [TestCase(1000)]
        public void BigSumTests(int len)
        {
            MyBigInteger first = GetRandomBigNumber(len);
            MyBigInteger second = GetRandomBigNumber(len);
            MyBigInteger expected = (MyBigInteger)BigInteger.Add((BigInteger)first, (BigInteger)second);

            Assert.AreEqual(expected, first + second);
        }

        [Test]
        [TestCase("0", "0", "0")]
        [TestCase("0", "1", "0")]
        [TestCase("0", "12", "0")]
        [TestCase("0", "123", "0")]
        [TestCase("5", "25", "125")]
        [TestCase("12", "65", "780")]
        [TestCase("99", "98", "9702")]
        [TestCase("12", "598", "7176")]
        [TestCase("123", "5890", "724470")]
        [TestCase("1234", "91834", "113323156")]
        [TestCase("66818", "52364", "3498857752")]
        [TestCase("123456789", "987654321", "121932631112635269")]
        [TestCase("1234567890123456", "1234567890123456", "1524157875323881726870921383936")]
        public void MultiplicationTests(string int1, string int2, string expectedProduct)
        {
            var first = new MyBigInteger(int1);
            var second = new MyBigInteger(int2);
            var expected = new MyBigInteger(expectedProduct);

            Assert.AreEqual(expected, first * second);
        }

        [Test]
        [TestCase(100)]
        [TestCase(1000)]
        public void BigMultiplicationTests(int len)
        {
            MyBigInteger first = GetRandomBigNumber(len);
            MyBigInteger second = GetRandomBigNumber(len);
            MyBigInteger expectedProduct = (MyBigInteger)BigInteger.Multiply((BigInteger)first, (BigInteger)second);

            Assert.AreEqual(expectedProduct, first * second);            
        }

        #region Helpers

        private MyBigInteger GetRandomBigNumber(int n)
        {
            var random = new Random((int)DateTime.Now.Ticks);
            var sb = new StringBuilder(n);

            for (int i = 0; i < n; ++i)
            {
                sb.Append(random.Next(10));
            }

            return new MyBigInteger(sb.ToString());
        }

        #endregion
    }
}
